/******************************************************************************

 @file frame_control_queue.c

 @brief Frame Control Queue Module Implementation
        基于POSIX消息队列(mqueue)实现，简洁且标准

 *****************************************************************************/

/******************************************************************************
 Includes
 *****************************************************************************/
#include "frame_control_queue.h"
#include <mqueue.h>
#include <errno.h>
// #include <fcntl.h>

/******************************************************************************
 Local Variables
 *****************************************************************************/

/* POSIX消息队列描述符 */
static mqd_t frameControlMsgQueue = (mqd_t)-1;

/******************************************************************************
 Public Functions
 *****************************************************************************/

/*!
 * @brief       初始化frameControl队列
 */
bool FrameControlQueue_init(void)
{
    struct mq_attr attr;

    /* 如果已经初始化，先关闭 */
    if (frameControlMsgQueue != (mqd_t)-1)
    {
        mq_close(frameControlMsgQueue);
        mq_unlink(FRAME_CONTROL_QUEUE_NAME);
    }

    /* 设置消息队列属性 */
    attr.mq_flags = 0;                      /* 阻塞模式 */
    attr.mq_maxmsg = FRAME_CONTROL_QUEUE_SIZE;  /* 最大消息数 */
    attr.mq_msgsize = sizeof(uint16_t);     /* 消息大小 */
    attr.mq_curmsgs = 0;                    /* 当前消息数（由系统设置）*/

    /* 创建消息队列 */
    frameControlMsgQueue = mq_open(FRAME_CONTROL_QUEUE_NAME, 
                                    O_CREAT | O_RDWR | O_NONBLOCK,
                                    0644,
                                    &attr);

    if (frameControlMsgQueue == (mqd_t)-1)
    {
        return false;
    }

    return true;
}

/*!
 * @brief       将frameControl添加到队列末尾
 */
bool FrameControlQueue_enqueue(uint16_t frameControl)
{
    int ret;

    if (frameControlMsgQueue == (mqd_t)-1)
    {
        return false;
    }

    /* 发送消息，优先级为0 */
    ret = mq_send(frameControlMsgQueue, 
                  (const char *)&frameControl, 
                  sizeof(uint16_t), 
                  0);

    if (ret == -1)
    {
        /* 如果队列满了，返回false */
        if (errno == EAGAIN)
        {
            return false;
        }
        return false;
    }

    return true;
}

/*!
 * @brief       从队列头部取出frameControl
 */
bool FrameControlQueue_dequeue(uint16_t *pFrameControl)
{
    ssize_t bytesRead;

    if (frameControlMsgQueue == (mqd_t)-1 || pFrameControl == NULL)
    {
        return false;
    }

    /* 接收消息（非阻塞） */
    bytesRead = mq_receive(frameControlMsgQueue, 
                           (char *)pFrameControl, 
                           sizeof(uint16_t), 
                           NULL);

    if (bytesRead == -1)
    {
        /* 如果队列为空，返回false */
        if (errno == EAGAIN)
        {
            return false;
        }
        return false;
    }

    return true;
}

/*!
 * @brief       查看队列头部的frameControl但不移除
 */
bool FrameControlQueue_peek(uint16_t *pFrameControl)
{
    int ret;

    if (frameControlMsgQueue == (mqd_t)-1 || pFrameControl == NULL)
    {
        return false;
    }

    /* 使用mq_peek查看消息但不移除 */
    ret = mq_peek(frameControlMsgQueue, 
                  (char *)pFrameControl, 
                  sizeof(uint16_t), 
                  0);

    if (ret == -1)
    {
        return false;
    }

    return true;
}

/*!
 * @brief       检查队列是否为空
 */
bool FrameControlQueue_isEmpty(void)
{
    struct mq_attr attr;

    if (frameControlMsgQueue == (mqd_t)-1)
    {
        return true;
    }

    if (mq_getattr(frameControlMsgQueue, &attr) == -1)
    {
        return true;
    }

    return (attr.mq_curmsgs == 0);
}

/*!
 * @brief       检查队列是否已满
 */
bool FrameControlQueue_isFull(void)
{
    struct mq_attr attr;

    if (frameControlMsgQueue == (mqd_t)-1)
    {
        return false;
    }

    if (mq_getattr(frameControlMsgQueue, &attr) == -1)
    {
        return false;
    }

    return (attr.mq_curmsgs >= attr.mq_maxmsg);
}

/*!
 * @brief       获取队列中当前的元素数量
 */
uint16_t FrameControlQueue_getCount(void)
{
    struct mq_attr attr;

    if (frameControlMsgQueue == (mqd_t)-1)
    {
        return 0;
    }

    if (mq_getattr(frameControlMsgQueue, &attr) == -1)
    {
        return 0;
    }

    return (uint16_t)attr.mq_curmsgs;
}

/*!
 * @brief       清空队列
 */
void FrameControlQueue_clear(void)
{
    uint16_t temp;

    if (frameControlMsgQueue == (mqd_t)-1)
    {
        return;
    }

    /* 持续接收消息直到队列为空 */
    while (FrameControlQueue_dequeue(&temp))
    {
        /* 清空操作 */
    }
}

/*!
 * @brief       批量入队多个frameControl
 */
uint16_t FrameControlQueue_enqueueBatch(const uint16_t *pFrameControls, uint16_t count)
{
    uint16_t enqueuedCount = 0;
    uint16_t i;

    if (frameControlMsgQueue == (mqd_t)-1 || pFrameControls == NULL || count == 0)
    {
        return 0;
    }

    for (i = 0; i < count; i++)
    {
        if (FrameControlQueue_enqueue(pFrameControls[i]))
        {
            enqueuedCount++;
        }
        else
        {
            /* 入队失败（队列可能已满），停止 */
            break;
        }
    }

    return enqueuedCount;
}

/*!
 * @brief       关闭并销毁队列（可选，用于清理资源）
 */
void FrameControlQueue_destroy(void)
{
    if (frameControlMsgQueue != (mqd_t)-1)
    {
        mq_close(frameControlMsgQueue);
        mq_unlink(FRAME_CONTROL_QUEUE_NAME);
        frameControlMsgQueue = (mqd_t)-1;
    }
}
